home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- This random number generator originally appeared in "Toward a Universal
- Random Number Generator" by George Marsaglia and Arif Zaman.
- Florida State University Report: FSU-SCRI-87-50 (1987)
-
- It was later modified by F. James and published in "A Review of Pseudo-
- random Number Generators"
-
- Converted from FORTRAN to C by Phil Linttell, James F. Hickling
- Management Consultants Ltd, Aug. 14, 1989.
-
- THIS IS THE BEST KNOWN RANDOM NUMBER GENERATOR AVAILABLE.
- (However, a newly discovered technique can yield
- a period of 10^600. But that is still in the development stage.)
-
- It passes ALL of the tests for random number generators and has a period
- of 2^144, is completely portable (gives bit identical results on all
- machines with at least 24-bit mantissas in the floating point
- representation).
-
- The algorithm is a combination of a Fibonacci sequence (with lags of 97
- and 33, and operation "subtraction plus one, modulo one") and an
- "arithmetic sequence" (using subtraction).
-
- On a Vax 11/780, this random number generator can produce a number in
- 13 microseconds.
- ************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <time.h>
-
- #define TRUE 1
- #define FALSE 0
-
- float u[97], c, cd, cm;
- int i97, j97, test;
-
- int rmarin(int ij, int kl);
- int ranmar(float rvec[], int len);
-
-
- int main()
- {
-
- float temp[100];
- int i;
- int ij, kl, len;
-
- /*These are the seeds needed to produce the test case results*/
-
- ij = 1802;
- kl = 9373;
-
- /*Do the initialization*/
-
- if (1 == rmarin(ij,kl))
- return 1;
-
- /*Generate 20000 random numbers*/
-
- len = 100;
- for ( i=0; i<=199 ; i++)
- if (1 == ranmar(temp, len))
- return 1;
-
- /*If the random number generator is working properly,
- the next six random numbers should be:
-
- 6533892.0 14220222.0 7275067.0
- 6172232.0 8354498.0 10633180.0
- */
-
- len = 6;
- if (1 == ranmar(temp, len))
- return 1;
-
- for ( i=0; i<=5; i++)
- printf("%12.1f\n",4096.0*4096.0*temp[i]);
-
- return 0;
- }
-
-
- /************************************************************************
- This is the initialization routine for the random number generator RANMAR()
- NOTE: The seed variables can have values between: 0 <= IJ <= 31328
- 0 <= KL <= 30081
- The random number sequences created by these two seeds are of sufficient
- length to complete an entire calculation with. For example, if several
- different groups are working on different parts of the same calculation,
- each group could be assigned its own IJ seed. This would leave each group
- with 30000 choices for the second seed. That is to say, this random
- number generator can create 900 million different subsequences -- with
- each subsequence having a length of approximately 10^30.
-
- Use IJ = 1802 & KL = 9373 to test the random number generator. The
- subroutine RANMAR should be used to generate 20000 random numbers.
- Then display the next six random numbers generated multiplied by 4096*4096
- If the random number generator is working properly, the random numbers
- should be:
- 6533892.0 14220222.0 7275067.0
- 6172232.0 8354498.0 10633180.0
- ************************************************************************/
-
- int rmarin(int ij, int kl)
- {
-
- float s, t;
- int i, j, k, l, m;
- int ii, jj;
-
- /* Change FALSE to TRUE in the next statement to test the
- random routine.*/
-
- test = TRUE;
-
- if ( ( ij < 0 || ij > 31328 ) ||
- ( kl < 0 || kl > 30081 ) )
- {
- printf ("RMARIN: The first random number seed must h